package io.babystar.modules.business.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.babystar.modules.business.dao.*;
import io.babystar.modules.business.entity.*;
import io.babystar.modules.business.service.StudentCourseDateService;
import io.babystar.modules.sys.dao.SysUserDao;
import io.babystar.modules.sys.dao.SysUserRoleDao;
import io.babystar.modules.sys.entity.SysUserEntity;
import io.babystar.modules.sys.entity.SysUserRoleEntity;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.babystar.common.utils.PageUtils;
import io.babystar.common.utils.Query;

import io.babystar.modules.business.service.StudentService;
import org.springframework.transaction.annotation.Transactional;


@Service("studentService")
public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> implements StudentService {

    @Autowired
    private StudentDao dao;
    @Autowired
    private ShopDao shopDao;
    @Autowired
    private ParentDao parentDao;
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;
    @Autowired
    private CourseStudentDao courseStudentDao;
    @Autowired
    private BusinessDao businessDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<StudentEntity> page = this.page(
                new Query<StudentEntity>().getPage(params),
                new QueryWrapper<StudentEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 获取预约信息
     * @return
     */
    @Override
    public PageUtils getAppointmentInfo(Long organizeId, Integer pageNuber, Integer pageSize, Map<String, Object> params) {
        Page<Map<String, Object>> page = new Page<>();
        String studentname = (String) params.get("key");
        params.put("organizeId", organizeId);
        params.put("studentname", studentname);
        Integer count = dao.getAppointmentCount(params);
        page.setTotal(count);
        page.setCurrent(pageNuber);
        page.setSize(pageSize);
        Long current = page.getCurrent();
        Long size = page.getSize();
        Long currentStart = size * current - size;
        params.put("currentStart", currentStart);
        params.put("size", size);
        page.setRecords(dao.getAppointmentInfo(params));
        return new PageUtils(page);
    }

    /**
     * 重写分页
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPageStudent(Map<String, Object> params) {
        Long organizeId = (Long) params.get("organizeid");
        List<Long> shops = new ArrayList<>();
        if (organizeId != null) {
            Map<String, Object> p = new HashMap<>();
            p.put("business_id", organizeId);
            List<ShopEntity> list = shopDao.selectByMap(p);
            for (ShopEntity shop : list) {
                shops.add(shop.getId());
            }
        }
        Page<StudentEntityAll> page = new Page<>();
        Integer count = dao.queryPageStudentCount(params);
        page.setTotal(count);
        Integer pageNuber = Integer.parseInt(params.get("page").toString());
        Integer pageSize = Integer.parseInt(params.get("limit").toString());
        page.setCurrent(pageNuber);
        page.setSize(pageSize);
        Long current = page.getCurrent();
        Long size = page.getSize();
        Long currentStart = size * current - size;
        params.put("currentStart", currentStart);
        params.put("size", size);
        page.setRecords(dao.queryPageStudent(params));

        return new PageUtils(page);
    }


    /**
     * 按日期排序并且分页
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPageStudentToSort(Map<String, Object> params) {
        Integer organizeId = (Integer)params.get("organizeid");
        List<Long> shops = new ArrayList<>();
        if(organizeId!=null){
            Map<String,Object> p = new HashMap<>();
            p.put("organizeid",organizeId);
            List<ShopEntity> list = shopDao.selectByMap(p);
            for(ShopEntity shop:list){
                shops.add(shop.getId());
            }
        }
        Page<StudentEntityAll> page = new Page<>();
        Integer count = dao.selectCount( new QueryWrapper<StudentEntity>()//.where("1=1",1)
                .like((!params.get("key").equals("")), "studentName", params.get("key").toString())
                .like(StringUtils.isNotEmpty(params.get("tel")+""),"matherPhone",params.get("tel")+"")
                .eq(!params.get("selectshopid").equals(""), "shopId", params.get("selectshopid").toString())
                .in(shops.size()>0,"shopId",shops)
                //.andNew(shops.size()==0,"1=2")
                //.orNew("1=1",1)
                .like((!params.get("key").equals("")), "studentMather", params.get("key").toString())
                .like(StringUtils.isNotEmpty(params.get("tel")+""),"matherPhone",params.get("tel")+"")
                .eq(!params.get("selectshopid").equals(""), "shopId", params.get("selectshopid").toString())
                .in(shops.size()>0,"shopId",shops)
                //.andNew(shops.size()==0,"1=2")
                );
        page.setTotal(count);
        Integer pageNuber = Integer.parseInt(params.get("page").toString());
        Integer pageSize = Integer.parseInt(params.get("limit").toString());
        page.setCurrent(pageNuber);
        page.setSize(pageSize);
        Long current = page.getCurrent();
        Long size = page.getSize();
        Long currentStart = size*current - size;
        params.put("currentStart",currentStart);
        params.put("size",size);
        params.put("organizeId",organizeId);
        page.setRecords(dao.queryPageStudentToSort(params));
        System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + page.getTotal());
        return new PageUtils(page);
    }

    /**
     * 查询获取机构下所有店铺信息
     * @param trainId
     * @return
     */
    @Override
    public List<ShopEntity> getShopInfo(Long trainId, Integer shopId){
        return dao.getShopInfo(trainId,shopId);
    }


    @Override
    public List<Map<String,Object>> getSignStudent(Map<String,String> map){
        return dao.getSignStudent(map);
    }

    @Override
    public List<Map<String,Object>> getStudentByShopId(Map<String,String> map){
        return dao.getStudentByShopId(map);
    }

    /**
     * 校对家长手机号重复性
     * @param matherphone
     * @return
     */
    @Override
    public Integer queryPhone(Long matherphone,Integer id){
        Integer count = null;
        try {
            count = dao.queryPhone(matherphone,id);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return count;
    }

    @Override
    public Integer queryMemberNum(Integer memberNum){
        return dao.queryMemberNum(memberNum);
    }

    /**
     * 保存学员
     * @param student
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map<String,String> saveStudent(StudentEntityAll student,SysUserEntity user){
        Map<String,String> result = new HashMap<String,String>();
        try {
            //校对家长手机号重复性
            Integer count = dao.queryPhone(Long.parseLong(student.getMatherphone()), null);
            if (count > 0) {
                result.put("code","400");
                result.put("msg","家长手机号码" + student.getMatherphone() + "已存在，请勿使用同一家长号码");
                return result;
            }

            // 会员卡编号
            SimpleDateFormat dateFormat = new SimpleDateFormat("yy");
            Date date = new Date();
            String nyr = dateFormat.format(date);
            String shopId = student.getShopid().toString();
            if (shopId.length() < 2) {
                shopId = "0" + shopId;
            }
            nyr = nyr + shopId;
            Integer memberNum = dao.queryMemberNum(Integer.parseInt(nyr));
            if (memberNum == null) {
                memberNum = Integer.parseInt(nyr + "0001");
            } else {
                memberNum += 1;
            }
            student.setCardnum(memberNum);
            student.setCreatetime(new Date());

            StudentEntity studentS = new StudentEntity();
            //1. 保存家长
            ParentEntity parent = new ParentEntity();
            parent.setParentPhone(student.getMatherphone());
            parent.setParentName(student.getStudentmather());
            parent.setOther(student.getOther());
            parent.setOtherPhone(student.getOtherphone());
            //家长角色0妈1爸2姑3姑父4姨5姨夫6婶7叔8奶9爷
            parent.setParentRole(1);
            parent.setRefereeName(student.getRefereename());
            //积分0
            parent.setResidualintegral(0);
            parent.setRemark(student.getRemark());
            parent.setCreateTime(new Date());
            parent.setShopId(student.getShopid());
            parentDao.insert(parent);

            //2.保存学员
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            StudentEntity studentEntity = new StudentEntity();
            studentEntity.setBusinessId(Integer.parseInt(user.getBusinessId()+""));
            studentEntity.setShopId(student.getShopid());
            studentEntity.setParentId(Integer.parseInt(parent.getId()+""));
            studentEntity.setStudentName(student.getStudentname());
            if(StringUtils.isNotEmpty(student.getStudentage())){
                studentEntity.setStudentAge(sdf.parse(student.getStudentage()));
            }
            studentEntity.setSchool(student.getSchool());
            studentEntity.setCardTypeId(student.getCardtype());
            studentEntity.setCardNum(student.getCardnum());
            studentEntity.setEquipment(student.getGiftequipment());
            studentEntity.setResidualClassHour(student.getResidualclasshour());
            studentEntity.setDueTime(student.getDuetime());
            studentEntity.setPayment(student.getPayment());
            studentEntity.setConsultant(student.getConsultant());
            studentEntity.setAddress(student.getAddress());
            studentEntity.setCreateTime(student.getCreatetime());
            studentEntity.setRemark(student.getRemark());
            studentEntity.setWeekLimit(student.getWeekLimit());
            dao.insert(studentEntity);
            //3.添加课程
            int id = Integer.parseInt(studentEntity.getId().toString());
            CourseStudentEntity courseStudentEntity = new CourseStudentEntity();
            courseStudentEntity.setCourseId(Integer.parseInt(student.getCourseId()));
            courseStudentEntity.setStudentId(id);
            courseStudentEntity.setSurplus(student.getResidualclasshour());
            courseStudentEntity.setTotal(student.getResidualclasshour());
            courseStudentEntity.setCreateTime(new Date());
            courseStudentDao.insert(courseStudentEntity);

            //4.生成登陆账号
            SysUserEntity sUser = sysUserDao.queryByUserName(student.getMatherphone());
            if(sUser!=null && sUser.getUserId()!=null){
                result.put("code","400");
                result.put("msg","家长手机号码" + student.getMatherphone() + "已存在，请勿使用同一家长号码");
                return result;
            }
            SysUserEntity sysUserEntity =  new SysUserEntity();
            sysUserEntity.setUsername(student.getMatherphone());
            //如果没有输入密码，默认123
            if(StringUtils.isEmpty(student.getPassword())){
                student.setPassword("123");
            }
            sysUserEntity.setPassword(student.getPassword());
            sysUserEntity.setSalt("");
            sysUserEntity.setEmail("1@1.com");
            //默认为当前操作人的机构
            sysUserEntity.setBusinessId(user.getBusinessId());
            //4家长
            sysUserEntity.setType(4);
            sysUserEntity.setParentTeacherId(parent.getId());
            sysUserEntity.setMobile(student.getMatherphone());
            //0:禁用   1:正常
            sysUserEntity.setStatus(1);
            sysUserEntity.setCreateUserId(user.getUserId());
            sysUserDao.insert(sysUserEntity);
            //5.生成角色
            SysUserRoleEntity sysUserRoleEntity = new SysUserRoleEntity();
            sysUserRoleEntity.setUserId(sysUserEntity.getUserId());
            sysUserRoleEntity.setRoleId(2L);
            sysUserRoleDao.insert(sysUserRoleEntity);
            result.put("code","0");
            result.put("msg","保存成功");

        } catch (Exception e) {
            e.printStackTrace();
            result.put("code","400");
            result.put("msg","保存失败");
            throw new RuntimeException();
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStudent(StudentEntityAll student) throws Exception{
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        System.out.println(student.getDuetime());
        StudentEntity studentEntity = new StudentEntity();
        studentEntity.setId(Integer.parseInt(student.getId()+""));
        studentEntity.setDueTime(student.getDuetime());
        if(StringUtils.isNotEmpty(student.getStudentage())){
            studentEntity.setStudentAge(sdf.parse(student.getStudentage()));
        }
        studentEntity.setCardTypeId(student.getCardtype());
        studentEntity.setShopId(student.getShopid());
        studentEntity.setWeekLimit(student.getWeekLimit());
        //课程不能改
        Map<String,Object> p = new HashMap<>();
        p.put("student_id",student.getId());
        List<CourseStudentEntity> csdList = courseStudentDao.selectByMap(p);
        if(csdList!=null && csdList.size()>0){
            for(CourseStudentEntity cs : csdList){
                cs.setCourseId(Integer.parseInt(student.getCourseId()));
                cs.setUpdateTime(new Date());
                courseStudentDao.updateById(cs);
            }
        }else{
            CourseStudentEntity cs = new CourseStudentEntity();
            cs.setStudentId(Integer.parseInt(student.getId()+""));
            cs.setCourseId(Integer.parseInt(student.getCourseId()));
            cs.setCreateTime(new Date());
            courseStudentDao.insert(cs);
        }

        studentEntity.setSchool(student.getSchool());
        studentEntity.setAddress(student.getAddress());
        studentEntity.setEquipment(student.getGiftequipment());
        studentEntity.setResidualClassHour(student.getResidualclasshour());
        studentEntity.setClassPeriod(student.getClassPeriod());
        studentEntity.setConsultant(student.getConsultant());
        studentEntity.setRemark(student.getRemark());
        studentEntity.setStudentName(student.getStudentname());
        studentEntity.setPayment(student.getPayment());

        StudentEntity stu = this.baseMapper.selectById(student.getId());
        ParentEntity parentEntity = new ParentEntity();
        parentEntity.setId(Long.parseLong(stu.getParentId()+""));
        parentEntity.setParentPhone(student.getMatherphone());
        parentEntity.setParentName(student.getStudentmather());
        parentEntity.setOtherPhone(student.getOtherphone());
        parentEntity.setOther(student.getOther());
        parentEntity.setShopId(student.getShopid());
        parentDao.updateById(parentEntity);

        Map<String,Object> params = new HashMap<>();
        params.put("business_id",stu.getBusinessId());
        params.put("type", 4);
        params.put("parent_teacher_id",stu.getParentId());
        List<SysUserEntity> userList = sysUserDao.selectByMap(params);

        if(userList!=null && userList.size()>0){
            SysUserEntity user = userList.get(0);
            user.setUsername(student.getMatherphone());
            sysUserDao.updateById(user);
        }

        this.baseMapper.updateById(studentEntity);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Integer> list){
        for(Integer id: list) {
            StudentEntity student = this.baseMapper.selectById(id);
            this.baseMapper.deleteById(student.getId());

            ParentEntity parent = this.parentDao.selectById(student.getParentId());
            ShopEntity shop = this.shopDao.selectById(student.getShopId());
            Map<String, Object> p = new HashMap<>();
            p.put("type", "4");
            p.put("username", parent.getParentPhone());
            p.put("parent_teacher_id",parent.getId());
            p.put("business_id", shop.getBusinessId());
            List<SysUserEntity> users = this.sysUserDao.selectByMap(p);
            if (users.size() > 0) {
                this.sysUserDao.deleteById(users.get(0).getUserId());
                Map<String, Object> rp = new HashMap<>();
                rp.put("user_id", users.get(0).getUserId());
                this.sysUserRoleDao.deleteByMap(rp);
                this.parentDao.deleteById(student.getParentId());
            }
        }
    }

    @Override
    public PageUtils queryPageStudentSchoolCount(Map<String, Object> params) {
        Integer count = dao.selectStudentSchoolCountListCount(params);
        Page<StudentEntityAll> page = new Page<>();
        page.setTotal(count);
        Integer pageNuber = Integer.parseInt(params.get("page").toString());
        Integer pageSize = Integer.parseInt(params.get("limit").toString());
        page.setCurrent(pageNuber);
        page.setSize(pageSize);
        long current = page.getCurrent();
        long size = page.getSize();
        long currentStart = size*current - size;
        params.put("currentStart",currentStart);
        params.put("size",size);
        page.setRecords(dao.queryPageStudentSchoolCountList(params));

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageStudentAddressCount(Map<String, Object> params) {
        Integer count = dao.selectStudentAddressCountListCount(params);
        Page<StudentEntityAll> page = new Page<>();
        page.setTotal(count);
        Integer pageNuber = Integer.parseInt(params.get("page").toString());
        Integer pageSize = Integer.parseInt(params.get("limit").toString());
        page.setCurrent(pageNuber);
        page.setSize(pageSize);
        long current = page.getCurrent();
        long size = page.getSize();
        long currentStart = size*current - size;
        params.put("currentStart",currentStart);
        params.put("size",size);
        page.setRecords(dao.queryPageStudentAddressCountList(params));

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageStudenPaymentSum(Map<String, Object> params) {
        Integer count = dao.selectStudentPaymentSumCount(params);
        Page<StudentEntityAll> page = new Page<>();
        page.setTotal(count);
        Integer pageNuber = Integer.parseInt(params.get("page").toString());
        Integer pageSize = Integer.parseInt(params.get("limit").toString());
        page.setCurrent(pageNuber);
        page.setSize(pageSize);
        long current = page.getCurrent();
        long size = page.getSize();
        long currentStart = size*current - size;
        params.put("currentStart",currentStart);
        params.put("size",size);
        page.setRecords(dao.queryPageStudentPaymentSumList(params));

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageClassEeliminationRate(Map<String, Object> params) {
        Integer count = dao.selectClassEeliminationRateCount(params);
        Page<StudentEntityAll> page = new Page<>();
        page.setTotal(count);
        Integer pageNuber = Integer.parseInt(params.get("page").toString());
        Integer pageSize = Integer.parseInt(params.get("limit").toString());
        page.setCurrent(pageNuber);
        page.setSize(pageSize);
        long current = page.getCurrent();
        long size = page.getSize();
        long currentStart = size*current - size;
        params.put("currentStart",currentStart);
        params.put("size",size);
        page.setRecords(dao.selectClassEeliminationRateList(params));

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageStudentPaymentRecords(Map<String, Object> params) {
        Integer count = dao.selectStudentPaymentRecordsCount(params);
        Page<StudentEntityAll> page = new Page<>();
        page.setTotal(count);
        Integer pageNuber = Integer.parseInt(params.get("page").toString());
        Integer pageSize = Integer.parseInt(params.get("limit").toString());
        page.setCurrent(pageNuber);
        page.setSize(pageSize);
        long current = page.getCurrent();
        long size = page.getSize();
        long currentStart = size*current - size;
        params.put("currentStart",currentStart);
        params.put("size",size);
        page.setRecords(dao.selectStudentPaymentRecordsList(params));

        return new PageUtils(page);
    }

    /**
     * 学生信息导入，异常回滚
     * @param successList
     * @param courseEntityList
     * @param memberCardEntityList
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ExcelStudent> importStudentInfo(List<ExcelStudent> successList, List<CourseEntity> courseEntityList,
                                                List<BaseMemberCardEntity> memberCardEntityList,
                                                String shopId, Integer organizeId) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<ExcelStudent> rsList = new LinkedList<>();
        for (ExcelStudent student : successList) {
            StudentEntity studentS = new StudentEntity();

            if (student.getMatherphone() == null || student.getMatherphone().trim().equals("")) {
                student.setIsSuccess(0);
                student.setDescription("家长手机不能为空！");
                rsList.add(student);
                continue;
            }
            try {
                student.setCourseId(Integer.parseInt(student.getCourseIdStr()));
            } catch (Exception e) {
                e.printStackTrace();
                student.setIsSuccess(0);
                student.setDescription("无法识别课程ID：" + student.getCourseIdStr());
                rsList.add(student);
                continue;
            }

            try {
                student.setResidualclasshour(Integer.parseInt(student.getResidualclasshourStr()));
            } catch (Exception e) {
                e.printStackTrace();
                student.setIsSuccess(0);
                student.setDescription("无法识别课时：" + student.getResidualclasshourStr());
                rsList.add(student);
                continue;
            }
            //判断课程存不存在
            courseLoop:
            for (CourseEntity courseEntity : courseEntityList) {
                if (courseEntity.getId().intValue() == student.getCourseId()) {
                    student.setCourseName(courseEntity.getName());
                    break courseLoop;
                }
            }
            if (student.getCourseName() == null || student.getCourseName().trim().equals("")) {
                student.setIsSuccess(0);
                student.setDescription("不存在的课程ID：" + (student.getCourseId() == null ? "没有课程ID" : student.getCourseId()));
                rsList.add(student);
                continue;
            }

            //判断会员卡存不存在
            cardLoop:
            for (BaseMemberCardEntity memberCardEntity : memberCardEntityList) {
                if (memberCardEntity.getCardName().equals(student.getCardtypeName())) {
                    student.setCardtype(memberCardEntity.getId().intValue());
                    break cardLoop;
                }
            }
            if (student.getCardtype() == null || student.getCardtype() == 0) {
                student.setIsSuccess(0);
                student.setDescription("不存在的会员卡类型：" + (student.getCardtypeName() == null ? "没有会员卡类型" : student.getCardtypeName()));
                rsList.add(student);
                continue;
            }
            System.out.println(student.getMatherphone());
            BeanUtils.copyProperties(studentS, student);
            // 校对家长手机号重复性
            Integer count = this.baseMapper.selectCount(
                    new QueryWrapper<StudentEntity>()
                            .eq("matherPhone", student.getMatherphone())
            );
            if (count > 0) {
                student.setIsSuccess(0);
                student.setDescription("手机号码" + student.getMatherphone() + "已存在，请勿使用重复的家长号码");
                rsList.add(student);
                continue;
            }

            studentS.setShopId(Integer.parseInt(shopId));
            studentS.setCreateTime(new Date());
            try {
                studentS.setDueTime(sdf.parse(student.getDuetimeStr()));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            // 保存学员信息
            this.save(studentS);

            // 存储学员课程关系
            CourseStudentEntity courseStudentEntity = new CourseStudentEntity();
            courseStudentEntity.setCourseId(student.getCourseId());
            courseStudentEntity.setStudentId(studentS.getId().intValue());
            courseStudentEntity.setSurplus(student.getResidualclasshour());
            courseStudentEntity.setTotal(student.getResidualclasshour());
            courseStudentEntity.setCreateTime(new Date());
            courseStudentDao.insert(courseStudentEntity);

            // 生产账号
            SysUserEntity sysUserEntity = new SysUserEntity();
            sysUserEntity.setUsername(student.getMatherphone());
            // 如果密码为空就设置默认密码
            if (StringUtils.isBlank(student.getPassword())) {
                student.setPassword("123456");
            }
            sysUserEntity.setPassword(student.getPassword());
            sysUserEntity.setBusinessId(organizeId.longValue());
            //sysUserEntity.setParentTeacherId(studentS.getId());
            // 家长
            sysUserEntity.setType(4);

            sysUserDao.insert(sysUserEntity);

            student.setIsSuccess(1);
            student.setDescription("导入成功！");
            rsList.add(student);
        }
        return rsList;
    }

}
